﻿using Alimentador.Foods;
using System.Windows;
using System.Windows.Controls;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows.Data;

namespace Alimentador.CustomControls
{
    /// <summary>
    /// Interaction logic for MealCtrl.xaml
    /// </summary>
    public partial class MealCtrl : UserControl
    {
        public delegate void MealFoodAddedEventDelegate(FoodBase foodAdded);
        public event MealFoodAddedEventDelegate MealFoodAddedEvent;

        public delegate void MealFoodRemovedEventDelegate(FoodBase foodRemoved);
        public event MealFoodRemovedEventDelegate MealFoodRemovedEvent;

        public delegate void MealQuantityChangeDelegate();
        public event MealQuantityChangeDelegate MealQuantityChangeEvent;

        public delegate void GetFocusEventDelegate(MealCtrl mc);
        public event GetFocusEventDelegate GotChildFocus;

        private List<FoodBase> m_FoodList = new List<FoodBase>();

        /// <summary>
        /// constructor
        /// </summary>
        public MealCtrl()
        {
            InitializeComponent();

            InitializeEvents();
        }

        /// <summary>
        /// Set initialize events
        /// </summary>
        private void InitializeEvents()
        {
            this.KeyDown += MealControl_KeyDown;
            MealFoodList.GotFocus += MealFoodList_GotFocus;
        }

        /// <summary>
        /// Selected focus for children.
        /// </summary>
        /// <param name="sender">object</param>
        /// <param name="e">RoutedEventArgs</param>
        private void MealFoodList_GotFocus(object sender, RoutedEventArgs e)
        {
            if (GotChildFocus != null)
            {
                GotChildFocus(this);
            }
        }

        private void Grid_DragEnter(object sender, DragEventArgs e)
        {
            if (!e.Data.GetDataPresent("FoodBase") || sender == e.Source)
            {
                e.Effects = DragDropEffects.None;
            }
        }

        private void Grid_Drop(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent("FoodBase"))
            {
                FoodBase droppedFood = e.Data.GetData("FoodBase") as FoodBase;
                if (droppedFood.GetItemType == FoodBase.ItemType.Food)
                {
                    AddFood((Food)droppedFood);
                }
            }
        }

        /// <summary>
        /// Adds the given Food to meal list
        /// </summary>
        /// <param name="droppedFood">Food</param>
        public void AddFood(Food droppedFood)
        {
            if (droppedFood == null)
                return;

            foreach (FoodBase fb in m_FoodList)
            {
                if (fb.GetName == droppedFood.GetName)
                {
                    MessageBox.Show("Alimento já adicionado a esta refeição. Em alternativa, poderá aumentar a quantidade.", "Aviso", MessageBoxButton.OK, MessageBoxImage.Exclamation);
                    return;
                }
            }

            MealFoodList.Visibility = Visibility.Visible;
            m_FoodList.Add(droppedFood.Clone());
            
            UpdateSource();


            if (MealFoodAddedEvent != null)
            {
                MealFoodAddedEvent(droppedFood);
            }
        }

        private void UpdateSource()
        {
            MealFoodList.ItemsSource = m_FoodList;
            ICollectionView view = CollectionViewSource.GetDefaultView(MealFoodList.ItemsSource);
            view.Refresh();
        }

        public string MealDescription
        {
            set
            {
                MealTitle.Text = value;
            }
            get
            {
                return MealTitle.Text;
            }
        }

        /// <summary>
        /// Returns the selected intem as Food or NULL if not found.
        /// </summary>
        /// <returns>Food</returns>
        internal Food GetSelectedItem()
        {
            if (MealFoodList.SelectedIndex != -1)
            {
                return (Food)MealFoodList.SelectedItem;
            }

            return null;
        }

        internal bool RemoveSelectedIndex(bool removeAll_bool = false)
        {
            if (removeAll_bool)
            {
                foreach (FoodBase fb in m_FoodList)
                {
                    if (MealFoodRemovedEvent != null)
                    {
                        MealFoodRemovedEvent(fb);
                    }
                }
                m_FoodList = new List<FoodBase>();
                UpdateSource();

                return true;
            }
            else
            {
                //System.Console.WriteLine(MealFoodList.IsFocused);
                if (MealFoodList.SelectedIndex != -1)
                {
                    MessageBoxResult msbr = MessageBox.Show("Pretende remover o alimento selecionado?", "Aviso", MessageBoxButton.YesNo, MessageBoxImage.Warning);
                    if (msbr == MessageBoxResult.Yes)
                    {
                        Food removedFood = (Food)MealFoodList.SelectedItem;
                        m_FoodList.Remove(removedFood);
                        //MealFoodList.Items.RemoveAt(MealFoodList.SelectedIndex);
                        UpdateSource();
                        if (MealFoodRemovedEvent != null)
                        {
                            MealFoodRemovedEvent(removedFood);
                        }

                        return true;
                    }
                }
            }
            return false;
        }

        private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
        {
            TextBox tb = (TextBox)sender;
            if (!string.IsNullOrEmpty(tb.Text))
            {
                DockPanel dp = (DockPanel)tb.Parent;
                Food fd = (Food)dp.DataContext;

                foreach (FoodBase fb in m_FoodList)
                {
                    Food fbCasted = (Food)fb;
                    if (fd.GetName == fbCasted.GetName)
                    {
                        double newValue = 0;
                        double.TryParse(tb.Text, out newValue);

                        double dif_newValue = newValue - fbCasted.Quantity;

                        fbCasted.Quantity = newValue;
                        foreach (FoodBase main_fb in MainWindow.m_foodList)
                        {
                            if (main_fb.GetName == fb.GetName)
                            {
                                ((Food)main_fb).Quantity += dif_newValue;
                                break;
                            }
                        }

                        if (MealQuantityChangeEvent != null)
                        {
                            MealQuantityChangeEvent();
                        }
                        break;
                    }
                }
            }
        }

        /// <summary>
        /// Handle the keyboard pressed event. "Delete" removes the selected item from list.
        /// </summary>
        /// <param name="sender">object</param>
        /// <param name="e">System.Windows.Input.KeyEventArgs</param>
        private void MealControl_KeyDown(object sender, System.Windows.Input.KeyEventArgs e)
        {
            if (e != null && e.Key == System.Windows.Input.Key.Delete)
            {
                if (MealFoodList != null && MealFoodList.SelectedItem != null)
                {
                    RemoveSelectedIndex();
                }
            }
        }

        internal void UnselectedChilds()
        {
            MealFoodList.SelectedIndex = -1;
        }

        public List<FoodBase> GetFoodList
        {
            get
            {
                return m_FoodList;
            }
        }
    }
}